home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / b_script.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-11  |  24.0 KB  |  691 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello  */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                    BinkleyTerm Script Handler Module                     */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  27. /*    AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  28. /*    USE   THIS  FILE  WITHOUT  HAVING   ACCEPTED  THE  TERMS  OF   THE    */
  29. /*    BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER  AGREEMENT AS YOU    */
  30. /*    ARE ABLE TO REACH WITH THE AUTHORS.                                   */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /*    The Authors can be reached at the following addresses:                */
  34. /*                                                                          */
  35. /*    Robert C. Hartman                      Vincent E. Perriello           */
  36. /*    Spark Software                         VEP Software                   */
  37. /*    427-3 Amherst Street                   111 Carroll Street             */
  38. /*    CS2032, Suite 232                      Naugatuck, CT 06770            */
  39. /*    Nashua, NH 03061                                                      */
  40. /*                                                                          */
  41. /*    FidoNet 1:132/101                      FidoNet 1:141/491              */
  42. /*    Data    (603) 888-8179                 Data    (203) 729-7569         */
  43. /*                                                                          */
  44. /*    Please feel free to contact us at any time to share your comments     */
  45. /*    about our software and/or licensing policies.                         */
  46. /*                                                                          */
  47. /*--------------------------------------------------------------------------*/
  48.  
  49. #include <stdio.h>
  50. #include <signal.h>
  51. #include <ctype.h>
  52. #include <conio.h>
  53. #include <string.h>
  54. #include <process.h>
  55. #include <stdlib.h>
  56.  
  57. #include "com.h"
  58. #include "xfer.h"
  59. #include "zmodem.h"
  60. #include "keybd.h"
  61. #include "sbuf.h"
  62. #include "sched.h"
  63. #include "externs.h"
  64. #include "prototyp.h"
  65.  
  66. static int nextline (char *);
  67. static int get_line (void);
  68.  
  69.  
  70. /*--------------------------------------------------------------------------*/
  71. /*   Define our current script functions for use in our dispatch table.     */
  72. /*--------------------------------------------------------------------------*/
  73.  
  74. static int script_baud (void);                   /* Set our baud rate to that
  75.                                                   * of remote */
  76. static int script_xmit (void);                   /* transmit characters out
  77.                                                   * the port   */
  78. static int script_pattern (void);                /* define a pattern to wait
  79.                                                   * for       */
  80. static int script_wait (void);                   /* wait for a pattern or
  81.                                                   * timeout      */
  82. static int script_dial (void);                   /* dial the whole number at
  83.                                                   * once      */
  84. static int script_areacode (void);               /* transmit the areacode out
  85.                                                   * the port */
  86. static int script_phone (void);                  /* transmit the phone number */
  87. static int script_carrier (void);                /* Test point, must have
  88.                                                   * carrier now  */
  89. static int script_session (void);                /* Exit script
  90.                                                   * "successfully"         */
  91. static int script_if (void);                     /* Branch based on pattern
  92.                                                   * match      */
  93. static int script_goto (void);                   /* Absolute branch           */
  94. static int script_timer (void);                  /* Set a master script
  95.                                                   * timeout        */
  96. static int script_bps100 (void);                 /* Send BPS/100 to remote
  97.                                                   * system      */
  98. static int script_break (void);                  /* Send a break to remote
  99.                                                   * system      */
  100. static int script_params (void);                 /* Set communication
  101.                                                   * parameters       */
  102. static int script_DOS (void);                    /* Execute a DOS command */
  103. static int script_abort (void);                  /* Abort a script during
  104.                                                   * certain hours */
  105. static int script_noWaZOO (void);                /* Turn off WaZOO for this
  106.                                                   * session only */
  107. struct dispatch
  108. {
  109.    char *string;
  110.    int (*fun) (void);
  111. };
  112.  
  113. static struct dispatch disp_table[] = {
  114.                                 {"baud", script_baud},
  115.                                 {"xmit", script_xmit},
  116.                                 {"pattern", script_pattern},
  117.                                 {"wait", script_wait},
  118.                                 {"dial", script_dial},
  119.                                 {"areacode", script_areacode},
  120.                                 {"phone", script_phone},
  121.                                 {"carrier", script_carrier},
  122.                                 {"session", script_session},
  123.                                 {"if", script_if},
  124.                                 {"goto", script_goto},
  125.                                 {"timer", script_timer},
  126.                                 {"speed", script_bps100},
  127.                                 {"break", script_break},
  128.                                 {"comm", script_params},
  129.                                 {"dos", script_DOS},
  130.                                 {"abort", script_abort},
  131.                                 {"NoWaZOO", script_noWaZOO},
  132.                                 {NULL, NULL}
  133. };
  134.  
  135. static char *script_dial_string = NULL;          /* string for 'dial'     */
  136. static char *script_phone_string = NULL;         /* string for 'phone'    */
  137. static char *script_areacode_string = "          ";/* string for 'areacode' */
  138.  
  139. #define PATTERNS 9
  140. #define PATSIZE 22
  141.  
  142. static char pattern[PATTERNS][PATSIZE];          /* 'wait' patterns       */
  143. static int scr_session_flag = 0;                 /* set by "session".     */
  144. static int pat_matched = -1;
  145. static char *script_function_argument;           /* argument for functions */
  146.  
  147. #define MAX_LABELS 50
  148. #define MAX_LAB_LEN 20
  149. static struct lab
  150. {
  151.    char name[MAX_LAB_LEN + 1];
  152.    long foffset;
  153.    int line;
  154. } labels[MAX_LABELS];
  155.  
  156. static long offset;
  157. static long script_alarm;                        /* used for master timeout */
  158. static int num_labels = 0;
  159. static int curline;
  160. static FILE *stream;
  161.  
  162. static char temp[256];
  163.  
  164. int do_script (phone_number)
  165. char *phone_number;
  166. {
  167.    register int i, j, k;
  168.    register char *c, *f;
  169.    char s[64], *t;
  170.    char *zstr = "";
  171.  
  172. /*--------------------------------------------------------------------------*/
  173. /* Reset everything from possible previous use of this function.            */
  174. /*--------------------------------------------------------------------------*/
  175.  
  176.    /* Get rid of cr/lf stuff if it is there */
  177.    if ((c = strchr (phone_number, '\r')) != NULL)
  178.       *c = '\0';
  179.    if ((c = strchr (phone_number, '\n')) != NULL)
  180.       *c = '\0';
  181.  
  182.    curline = 0;
  183.    pat_matched = -1;
  184.    num_labels = 0;
  185.    *script_areacode_string = '\0';               /* reset the special strings */
  186.    script_dial_string = script_phone_string = NULL;
  187.    script_alarm = 0L;                            /* reset timeout */
  188.    for (i = 0; i < PATTERNS; i++)
  189.       {
  190.       pattern[i][0] = 1;
  191.       pattern[i][1] = '\0';                      /* and the 'wait' patterns   */
  192.       }
  193.    scr_session_flag = 0;
  194.  
  195. /*--------------------------------------------------------------------------*/
  196. /* Now start doing things with phone number:                                */
  197. /*     1) construct the name of the script file into temp                   */
  198. /*     2) build script_dial_string, script_areacode_string and              */
  199. /*        script_phone_string                                               */
  200. /*--------------------------------------------------------------------------*/
  201.  
  202.    if (script_path == NULL)
  203.       strcpy (temp, BINKpath);                   /* get our current path      */
  204.    else strcpy (temp, script_path);              /* Otherwise, use the given
  205.                                                   * path */
  206.  
  207.    t = c = &temp[strlen (temp)];                 /* point past paths          */
  208.    f = phone_number;                             /* then get input side       */
  209.    while (*++f != '\"')                          /* look for end of string    */
  210.       {
  211.       if ((*c++ = *f) == '\0')                   /* if premature ending,      */
  212.          return (0);
  213.       }
  214.    *c = '\0';                                    /* Now we have the file name */
  215.    strcpy (s, t);
  216.  
  217.    c = script_areacode_string;                   /* point to area code        */
  218.    if (*++f)                                     /* if there's anything left, */
  219.       {
  220.       script_dial_string = f;                    /* dial string is rest of it */
  221.       for (i = 0; i < 10, *f != '\0', *f != '-'; i++)
  222.          *c++ = *f++;                            /* copy it for 'areacode'    */
  223.       }
  224.    *c = '\0';                                    /* terminate areacode        */
  225.    if (*f && *f++ == '-')                        /* If more, and we got '-',  */
  226.       script_phone_string = f;                   /* point to phone string     */
  227.  
  228.    if (script_dial_string == NULL)               /* To make the log happy,    */
  229.       script_dial_string ="";                    /* NULL => 0-length string   */
  230.  
  231.  
  232. /*--------------------------------------------------------------------------*/
  233. /* Finally open the script file and start doing some WORK.                  */
  234. /*--------------------------------------------------------------------------*/
  235.  
  236.    status_line (":Dialing %s with script \"%s\"", script_dial_string, s);
  237.  
  238.    if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  239.       {
  240.       status_line ("!Could not open script %s", temp);
  241.       return (0);                                /* no file, no work to do    */
  242.       }
  243.  
  244.    k = 0;                                        /* default return is "fail"  */
  245.    while (nextline (NULL))                       /* Now we parse the file ... */
  246.       {
  247.       k = 0;                                     /* default return is "fail"  */
  248.       for (j = 0; (c = disp_table[j].string) != NULL; j++)
  249.          {
  250.          i = strlen (c);
  251.          if (strnicmp (temp, c, i) == 0)
  252.             {
  253.             script_function_argument = temp + i + 1;
  254.             k = (*disp_table[j].fun) ();
  255.             break;
  256.             }
  257.          }
  258.  
  259.       if (script_alarm && timeup (script_alarm)) /* Check master timer */
  260.          {
  261.          status_line ("+Master script timer expired");
  262.          k = 0;
  263.          }
  264.  
  265.       if (!k || scr_session_flag)                /* get out for failure or    */
  266.          break;                                  /* 'session'.                */
  267.  
  268.       }
  269.    fclose (stream);                              /* close input file          */
  270.    if (!k)
  271.       {
  272.       status_line ("+Script \"%s\" failed at line %d", s, curline);
  273.       DTR_OFF ();
  274.       timer (1);
  275.       }
  276.    return (k);                                   /* return last success/fail  */
  277. }
  278.  
  279. static script_xmit ()
  280. {
  281.    mdm_cmd_string (script_function_argument, 1);
  282.    return (1);
  283. }
  284.  
  285. static script_DOS ()
  286. {
  287.    close_up ();
  288.    vfossil_cursor (1);
  289.    b_spawn (script_function_argument);
  290.    come_back ();
  291.    return (1);
  292. }
  293.  
  294. static script_abort ()
  295. {
  296.    int s1, s2, e1, e2;
  297.    int cur_hour, cur_minute, j;
  298.    int starttime, endtime, us;
  299.  
  300.    /* If we don't get everything we need, it is a true abort */
  301.    if (sscanf (script_function_argument, "%d:%d %d:%d", &s1, &s2, &e1, &e2) != 4)
  302.       return (0);
  303.  
  304.    dostime (&cur_hour, &cur_minute, &j, &j);
  305.    starttime = s1 * 60 + s2;
  306.    endtime = e1 * 60 + e2;
  307.    us = cur_hour * 60 + cur_minute;
  308.  
  309.    if (endtime < starttime)
  310.       {
  311.       endtime += 60 * 60;
  312.       }
  313.  
  314.    if (us < starttime)
  315.       {
  316.       us += 24 * 60;
  317.       }
  318.  
  319.    if ((us >= starttime) && (us <= endtime))
  320.       {
  321.       return (0);
  322.       }
  323.  
  324.    return (1);
  325. }
  326.  
  327. static script_break ()
  328. {
  329.    int t;
  330.  
  331.    t = atoi (script_function_argument);
  332.    if (t == 0)
  333.       t = 100;
  334.  
  335.    if (old_fossil)
  336.       {
  337.       status_line ("!Revision 3 FOSSIL does not support BREAK signal");
  338.       }
  339.    else
  340.       {
  341.       send_break (t);
  342.       }
  343.    return (1);
  344. }
  345.  
  346. static script_params ()
  347. {
  348.    char c;
  349.    int i, j;
  350.  
  351.    sscanf (script_function_argument, "%d%c%d", &i, &c, &j);
  352.    comm_bits = (i == 7) ? BITS_7 : BITS_8;
  353.    switch (toupper (c))
  354.       {
  355.       case 'E':
  356.          parity = EVEN_PARITY;
  357.          break;
  358.  
  359.       case 'O':
  360.          parity = ODD_PARITY;
  361.          break;
  362.  
  363.       case 'N':
  364.          parity = NO_PARITY;
  365.          break;
  366.       }
  367.    stop_bits = j;
  368.    MDM_ENABLE (btypes[baud].rate);
  369.    return (1);
  370. }
  371.  
  372. static script_bps100 ()
  373. {
  374.    char junk[10];
  375.  
  376.    sprintf (junk, "%d", cur_baud / 100);
  377.    mdm_cmd_string (junk, 0);
  378.    return (1);
  379. }
  380.  
  381. static script_areacode ()
  382. {
  383.    mdm_cmd_string (script_areacode_string, 0);
  384.    return (1);
  385. }
  386.  
  387. static script_phone ()
  388. {
  389.    mdm_cmd_string (script_phone_string, 0);
  390.    return (1);
  391. }
  392.  
  393. static script_dial ()
  394. {
  395.    mdm_cmd_string (script_dial_string, 0);
  396.    mdm_cmd_char (CR);                            /* terminate the string      */
  397.    if (modem_response (7500) == 2)               /* we got a good response,   */
  398.       {
  399.       timer (20);                                /* wait for other side       */
  400.       return (1);                                /* Carrier should be on now  */
  401.       }
  402.    return (0);                                   /* no good */
  403. }
  404.  
  405. static script_carrier ()
  406. {
  407.    return (CARRIER);
  408. }
  409.  
  410. static script_session ()
  411. {
  412.    ++scr_session_flag;                           /* signal end of script */
  413.    return (1);
  414. }
  415.  
  416. static script_pattern ()
  417. {
  418.    register int i, j;
  419.    register char *c;
  420.  
  421.    c = script_function_argument;                 /* copy the pointer   */
  422.    i = atoi (c);                                 /* get pattern number */
  423.    if (i < 0 || i >= PATTERNS)                   /* check bounds */
  424.       return (0);
  425.    c += 2;                                       /* skip digit and space */
  426.    for (j = 1; j <= PATSIZE, *c != '\0'; j++)
  427.       pattern[i][j] = *c++;                      /* store the pattern */
  428.    pattern[i][j] = '\0';                         /* terminate it here */
  429.    return (1);
  430. }
  431.  
  432. static script_wait ()
  433. {
  434.    long t1, timerset ();
  435.    register int i, j;
  436.    register char c;
  437.    int wait;
  438.    int got_it = 0;
  439.  
  440.    pat_matched = -1;
  441.    wait = 100 * atoi (script_function_argument); /* try to get wait length */
  442.    if (!wait)
  443.       wait = 4000;                               /* default is 40 seconds     */
  444.    t1 = timerset (wait);
  445.    cprintf ("\r\n\033[K");
  446.    while (!timeup (t1) && !KEYPRESS ())
  447.       {
  448.       if (script_alarm && timeup (script_alarm)) /* Check master timer */
  449.          break;                                  /* Oops, out of time...      */
  450.  
  451.       if (!CHAR_AVAIL ())                        /* if nothing ready yet,     */
  452.          {
  453.          time_release ();                        /* give others a shot        */
  454.          continue;                               /* just process timeouts     */
  455.          }
  456.       t1 = timerset (wait);                      /* reset the timeout         */
  457.       c = (char) MODEM_IN ();                    /* get a character           */
  458.       if (!c)
  459.          continue;                               /* ignore null characters    */
  460.       if (c >= ' ')
  461.          {
  462.          WRITE_ANSI (c & 0x7f);
  463.          }
  464.       for (i = 0; i < PATTERNS; i++)
  465.          {
  466.          j = pattern[i][0];                      /* points to next match char */
  467.          if (c == pattern[i][j])                 /* if it matches,            */
  468.             {
  469.             ++j;                                 /* bump the pointer          */
  470.             pattern[i][0] = (char) j;            /* store it                  */
  471.             if (!pattern[i][j])                  /* if at the end of pattern, */
  472.                {
  473.                ++got_it;
  474.                pat_matched = i;
  475.                goto done;
  476.                }
  477.             }
  478.          else
  479.             {
  480.             pattern[i][0] = 1;                   /* back to start of string   */
  481.             }
  482.          }
  483.       }
  484. done:
  485.    for (i = 0; i < PATTERNS; i++)
  486.       {
  487.       pattern[i][0] = 1;                         /* reset these for next time */
  488.       }
  489.    if (!got_it)                                  /* timed out, look for label */
  490.       {
  491.       /* First skip over the numeric argument for "wait"   */
  492.       while ((c = *script_function_argument) && isdigit(c))
  493.          script_function_argument++;
  494.  
  495.       /* Then skip over any spaces that follow it          */
  496.       while ((c = *script_function_argument) && isspace(c))
  497.          script_function_argument++;
  498.  
  499.       /* Now, if there's anything more, treat it as a goto */
  500.       if (*script_function_argument)
  501.          return (script_goto ());
  502.       }         
  503.    return (got_it);
  504. }
  505.  
  506. static script_baud ()
  507. {
  508.    int a, b;
  509.  
  510.    if ((b = atoi (script_function_argument)) != 0)
  511.       {
  512.       a = autobaud;
  513.       autobaud = 0;
  514.       set_baud (b, 0);
  515.       autobaud = a;
  516.       }
  517.    return (1);
  518. }
  519.  
  520. static script_goto ()
  521. {
  522.    int i;
  523.  
  524.    /* First see if we already found this guy */
  525.    for (i = 0; i < num_labels; i++)
  526.       {
  527.       if (stricmp (script_function_argument, labels[i].name) == 0)
  528.          {
  529.          /* We found it */
  530.          fseek (stream, labels[i].foffset, SEEK_SET);
  531.          curline = labels[i].line;
  532.          return (1);
  533.          }
  534.       }
  535.  
  536.    return (nextline (script_function_argument));
  537. }
  538.  
  539. static script_if ()
  540. {
  541.  
  542.    /* First, move past any spaces that might be between IF and value.   */
  543.  
  544.    while (isspace (*script_function_argument) && (*script_function_argument))
  545.       ++script_function_argument;
  546.  
  547.    /* Then check for digit. Only current legal non-digit is 'B' but     *
  548.     * that might change with time...                                    *
  549.     *                                                                   *
  550.     * If it's a non-digit,                                              *
  551.     *                                                                   *
  552.     *    a) look for "BPS". If not, return error.                       *
  553.     *                                                                   *
  554.     *    b) compare current baud with number that should follow         *
  555.     *       "BPS". If no match, return error.                           *
  556.     *                                                                   *
  557.     * If it's a digit, compare the number of the last pattern we matched*
  558.     * with the argument value. If no match, return error.               *
  559.     *                                                                   */
  560.  
  561.    if (!isdigit(*script_function_argument))
  562.       {
  563.       if (strnicmp (script_function_argument, "BPS", 3) != 0)
  564.          return (1);
  565.  
  566.       script_function_argument += 3;
  567.       if (atoi (script_function_argument) != cur_baud)
  568.          return (1);
  569.       }
  570.  
  571.    else
  572.       if (atoi (script_function_argument) != pat_matched)
  573.      return(1);
  574.    
  575.    /* We matched, skip the pattern number and the space                 */
  576.  
  577.    while ((*script_function_argument) &&
  578.           (!isspace (*script_function_argument)))
  579.       ++script_function_argument;
  580.  
  581.    while (isspace (*script_function_argument))
  582.       ++script_function_argument;
  583.  
  584.    return (script_goto ());
  585. }
  586.  
  587. static script_timer ()                           /* Set a master timer */
  588. {
  589.    int i;
  590.    long timerset ();
  591.  
  592.    /*
  593.     * If we got a number, set the master timer. Note: this could be done many
  594.     * times in the script, allowing you to program timeouts on individual
  595.     * parts of the script. 
  596.     */
  597.  
  598.    if (i = atoi (script_function_argument))
  599.       script_alarm = timerset (i * 100);
  600.  
  601.    return (1);
  602. }
  603.  
  604. static script_noWaZOO ()
  605. {
  606.    ++no_WaZOO_Session;
  607.    return (1);
  608. }
  609.  
  610. static int nextline (str)
  611. char *str;
  612. {
  613.    char save[256];
  614.  
  615.    if (str != NULL)
  616.       strcpy (save, str);
  617.    else save[0] = '\0';
  618.  
  619.    while (get_line ())                           /* Now we parse the file ... */
  620.       {
  621.       if (!isalpha (temp[0]))
  622.          {
  623.          if (temp[0] != ':')
  624.             {
  625.             /* This line is a comment line */
  626.             continue;
  627.             }
  628.          else
  629.             {
  630.             /* It is a label */
  631.             if (num_labels >= MAX_LABELS)
  632.                {
  633.                status_line ("!Too many labels in script");
  634.                return (0);
  635.                }
  636.             strcpy (labels[num_labels].name, &(temp[1]));
  637.             labels[num_labels].foffset = offset;
  638.             labels[num_labels].line = curline;
  639.             ++num_labels;
  640.  
  641.             if (stricmp (&temp[1], save))
  642.                {
  643.                continue;
  644.                }
  645.             else
  646.                {
  647.                return (1);
  648.                }
  649.             }
  650.          }
  651.  
  652.       if (!save[0])
  653.          return (1);
  654.       }
  655.  
  656.    return (0);
  657. }
  658.  
  659. static int get_line ()
  660. {
  661.    char *c;
  662.    char j[100];
  663.  
  664.    if (fgets (temp, 255, stream) == NULL)
  665.       return (0);
  666.  
  667.    ++curline;
  668.  
  669.    /* Deal with side effects of opening the script file in binary mode  */
  670.  
  671.    c = &temp [strlen (temp) - 1];
  672.    while ((*c == '\r') || (*c == '\n'))
  673.      c--;
  674.    
  675.    *++c = '\0';         /* Don't want newlines, terminate after text    */
  676.  
  677.    sprintf (j, "Script Line %03d: %-58.58s", curline, temp);
  678.    if ((un_attended || doing_poll) && fullscreen)
  679.       {
  680.       sb_move (filewin, 2, 2);
  681.       sb_puts (filewin, j);
  682.       sb_show ();
  683.       }
  684.    else
  685.       {
  686.       cprintf ("\r\n%s", j);
  687.       }
  688.    offset = ftell (stream);
  689.    return (1);
  690. }
  691.